home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ASMVEG3.ZIP
/
ASMVEG3.TXT
next >
Wrap
Text File
|
1996-12-23
|
19KB
|
441 lines
Assembly Language for Veggies (And C programmers) Part 3.
Welcome back to assembly for veggies.... Well I've said a lot about real
simple stuff now.. perhaps it's time to provide you lot with some decent
assorted infos?
Where to start is the BIG question.. there's a hell of a lot to know about your
PC, and it's overall structure.... I said you'd have to get akin with the
hardware, so why don't we leap into some hardware discussions this section
(consider it a primer to bring you into a betterunderstanding - because you
use the hardware directly quite a bit in ASM)..
I will leap in by talking a bit about the IBM machine... (This could be a
long story ;-)...)
The original IBM PC was based around the Intel 8088 CPU. CPU Stands for
Central Processing Unit and is the "Brain" of the computer.. In fact, a
computer can be correlated very well with the human body (thus the body is
often referred to as a biological computer!!).
The CPU is equivilant to the human brain. It controlls everything else, and
does MOST of the workload. The people who made the 8088 (Intel) soon
progressed with the 80286, 386 and 486 chips which are Upward compatible with
the 8088 - this means that they will correctly run anything made for an
EARLIER version (IE 386 runs all 286, 8088 stuff too) of the CPU. Each new CPU
added extra features, not found in earlier models, thus the later models are
NOT Downward compatible. (OK the order here may seem wrong, but if you follow
the logic that everything is compatible as you go up the chain (88 - 286 - 386
-486), but not down the chain (486 - 386 - 286 - 88) you'll understand.
The CPU alone is the clever but, but put it on it's own and it won't do a
lot... you need to add INTERFACING around it. you also need to provide a
source of POWER to run it, and give it a TASK to perform. Remember the
highlighted words - we'll look at each of them now...
POWER : In human terms, we'd be looking at the digestive, lung - blood system.
to simplify things, we say food goes in, gets converted into the right sor of
energy to run the brain, piped there via the blood/veins and is uses by the
brain in it's normal operation.
In computer terms we have a POWER SUPPLY - it takes mains voltage, converts it
to the DC 5v and 12v required for the CPU and pipes it there via metal wires
where it is used in the action of processing.
INTERFACING : This topic is huge and basicly covers the rest of the body...
it ill the input and output devices... there are many sub-systems here to be
considered - for example the eyeball-brain connection is like the VGA-CPU
connection and so forth.. I'll have a lot more to say about this lter... Oh,
and it's often called I/O, but I don't like that term as it is easily confused
with I/O external (serial, parallel ports etc) to the machine... the kind of
interfacing I mean is between the CPU and the other components inside the
case...
TASK : Well, you're always doing something - take breathing for example... so
too the CPU must always be doing something - it's forever running a program of
some sort - remember, DOS or whatever is just a program to the CPU, and it
makes no distinction between one program and another...
So what do we have so far? A CPU capable of processing instructions fed to
it, and the unknown quantity known as Interfacing...
Ok... well believe it or not the CPU is really pretty dumb... it has a set
of about 150 or so separate instructions that it recognises and can do things
with.. It has no memory WHAT SO EVER!!!
As you know, it has some registers and that's it! Pretty poor, eh? well
that's because it's designed as a CONTROLLER... just as your muscles take
instructions from the brain and actually do the work, so too the CPU tells
it's "workers" what to do and that's what actually produces results...
Let's look at all the bits put in round the CPU to support it.
The original IBM Machine was designed around standard off-the-shelf chips. In
fact you can take a bare IBM Motherboard (XT I mean), wander down to Dick
Smith, Radio parts and maybe one other shop and buy all the bits (with one
important exception) for no more than a dollar or two each - there's about 60
of them to buy, and a complete set at today's prices is about $180. There's
only 1 set of chips you can't get - because they contain the BIOS and have to
be pre-programmed by IBM before you buy...
Anyhow, I digress! The point is that everybody (indeed right thru to the 486
machines) has remained compatible with this original design - thus anything
you write to work with the basic setup will run on anything...
Here's what they put in:
RAM up to 640k of RAM in 10 banks
ROM up to 64k in 1 bank
8237 a chip that controls the DMA
8255 parallel I/O chip for miscellaneous control - NOT the printer ports!!
8253 programmable timer for assorted timing (including the clock!)
8259 interrupt controller for handling important hardware events
An exhaustive discussion of the actual functions of each chip would take YONKS
so I'll leave it here for now... suffice to say that that's the stuff that
does all the basic I/O internal to the motherboard.... it is essential that
all these bits work before the machine will fire up..
IBM Then added the expansion bus (wonderfull idea!!) and designed the video
card, the serial card, the parallel and floppy disk drive cards. These used
more garden variety chips that slotted into pre-allocated spaces inside the
design of the PC.. This allocation of specic locations to specific parts of
the PC was to be a bad shortcoming indeed (if they allowed us to relocate the
hardware elswhere we'd be able to have as much as 768k of RAM to use in most
cases, maybe even as much as 896k in good designs!!!).
BASIC PC MEMORY MAP
FFFF
F000 F000-FFFF System BIOS lives here (usually only top 8k used)
E000 E000-EFFF Traditionally add on BIOS (Normally free)
D000 D000-DFFF Traditionally add on BIOS (Normally free)
C800-CFFF Add on card useage (Usually XT Type HDD contolleer BIOS)
C000 C000-C7FF Add on card useage (Usually extra VGA bios)
B800-BFFF CGA Video RAM
B000 B000-B7FF MONO Video RAM
A000-AFFF EGA/VGA Video RAM (Graphics modes)
A000 --- 640k RAM --- LIMIT of user RAM
9000 --- 576k RAM
8000 --- 512k RAM
7000 --- 448k RAM
6000 --- 384k RAM
5000 --- 320k RAM
4000 --- 256k RAM
3000 --- 192k RAM
2000 --- 128k RAM
1000 --- 64k RAM
0000 --- bottom of memory ---
In these modern times, things like EMS make use sof the "empty" D and E
blocks... You should be able to see that it is impossible to add more
"conventional" memory becuse of the hard design that says you have to use the
A block as VGA RAM (If you didn't have VGA you COULD add extra RAM on some
sort of custom design card, hack DOS and use the extra 64k as normal RAM, but
why bother!!)
It is now normal to reserve all of the A and B blocks for video RAM, the
E000-E800 for video BIOS, the E800-EFFF block for XT Hard disk BIOS's, and the
D & E blocks for EMS drivers. The F block is usually left alone, it's use
bieng decided by the particular designers of any given motherboard (for
example to save a wire, IBM actually mde their bios appear TWICE in memory -
once from F000:FA00 - F000:FFFF, and once some 16k lower... there was only
one physical copy in the hardware, but because they left out a wire
(apparently for simpstic design of the motherboard) it appears twice in the
memory map. Many true-blue PC Programs relied on this fact (Flight simulator 1
bieng the most memorable) by directly calling routines from their 16-lower
address instead of using the correct method of going via the interrupts...
clone makers didn't copy IBM's BUG and so the software would crash becaus the
routines it wanted weren't there!! (But soon the clone makers got wise and
fixed that one up - by making the same bug as IBM!!! one motherboard I saw
physically had had the wire cut with a sharp knife (Effectively leaving it
out) to make the board more compatible!!)
note that the 80xxx range of chips (after a reset or power on) always begin
executing from address F000:FFF0 - thus the bios should always be present in
that location!! normally there'd be a JMP instruction to lower down (seeing as
that address is only 16 bytes from the end of the memory map!) in the BIOS
where the initial self test & startup routines execute. The initial self test
routines are often called the POST (Power on self test) - they initialize the
video, floppy, hard disks, set up all the onboard 82xx chips and so on... then
search for the first bootable device.
The first 64k of RAM is used in part by the 80xxx and the BIOS and by DOS...
0000-0100 - 256 4 byte entries hold the actual addresses that each interrupt
relates to - so if you want to know where interrupt 2F is pointing, look at
the 4 bytes starting at offset (2Fh=47d 47x4=188d=BCh) 00BC... (or use the
DOS getintvector call!)
0101-03FF - undoccumented mystery - probably used by BIOS internals or even
free.
0400-04FF - BIOS Data table - holds data critical to normal working of BIOS
0500-05FF - DOS Data table - holds critical data that BIOS and DOS use
0600-7BFF - undoccumented mystery - apparently free or for later expansion.
7C00-xxxx - When you boot up, the BIOS reads track 0, head 0, sector one of
the first bootable disk into memory starting here at 0000:7C00 and hands
control to 0000:7C00. Everything from this point on is dependant on what this
boot track tells the machine to do. In DOS based systems, it loads the two
hidden system files into RAM (thus starting DOS) or proclaims "non-system disk
or disk error..."
There's also a similar I/O map for the hardware chips - the 80xxx series can
access up to 64k worth of I/O ports, but the design of the IBM allows the use
of only the first 400h (1024d) ports (which is heaps!!)
I/O port Map
Port # Use Chip Number used by IBM
000-00F DMA Registers 8237
010-01F AT Second DMA Chip 8237 #2
020-027 Interrupt controller 8259
028-03F AT Interrupt controller 8259 #2
040-047 Timer chip 8253
048-05F AT Timer chip 8253 #2
060-06F Parallel Chip (NOT LPTx!) 8255
070-07F AT NMI Mask registers
080-083 DMA Page registers
084-09F AT DMA Page registers
0Ax Free
0Bx Free
0Cx Free
0Dx Free
0Ex Free
0Fx Free
100-1FF Due to a stuff up in IBM, all ports in the range 000-0FF appear
again in this range - they didn't decode address line A8!!
200-20F Game (Joystick) D/A converters & fire buttons
210-217 XT Expansion unit
218-277 Free (soundblaster usually at 220h)
278-27F LPT3: 74LS273/74LS373
280-2E7 Free
2E8-2EF COM4: 8250
2F0-2F7 Free
2F8-2FF COM2: 8250
300-31F Prototype card
320-32F Hard disk use WD10x00 MFM HDD Series Chipset
330-377 Free
378-37F LPT2: 74LS273/74LS373
380-38F SDLF Communications Card (IBM Failure of a design!!)
390-39F Free
3A0-3AF Binary Synchronous Comms (Another IBM Failed design!)
3B0-3BB MONO Video MC6845
3BC-3BF LPT1: 74LS273/74LS373
3C0-3CF EGA/VGA Video
3D0-3DF CGA Video MC6845
3E0-3E7 Free
3E8-3EF COM3: 8250
3F0-3F7 Floppy Disk controller NEC uPD765c
3F8-3FF COM1: 8250
Basicly that's it!! As I said before, an exhaustive referance to individual
chips would be a large hassle!, not to mention hundreds of pages long!! So I
won't bother!
INTERRUPTS
Interrupts are the other big deal on the PC .. there's too many to list
individually, so i'll cover them in blocks..
INT# Made by Use
0 80xxx divide by Zero error
1 80xxx single stepper
2 80xxx NMI
3 80xxx Breakpoint
4 80xxx Overflow
5 BIOS Printscreen (Why the fuk did they use 5!!!)
6,7 IBM Reserved
8 8259 IRQ0 - Timer tick - timeclock basicly
9 8259 IRQ1 - Keypressed - calls BIOS readkey from 8048 KB CPU
A 8259 IRQ2 - EGA/VGA Vertical retrace, 8087 error
B 8259 IRQ3 - COM2: I/O done COM4: I/O done
C 8259 IRQ4 - COM1: I/O done COM3: I/O done
D 8259 IRQ5 - Hard disk data ready/needed
E 8259 IRQ6 - Floppy disk data ready/needed
F 8259 IRQ7 - Parallel printer, SoundBlaster loadx
10 to
1F BIOS Bios routines, pointers etc.
20 to
3F DOS DOS routines, pointers, drivers etc.
40 HDD HDD Puts original floppy INT13 call here
41 HDD Points to table holding HDD head, cyl etc. data
42 EGA/VGA Puts original video routines here
43 EGA/VGA Low 128 video char font pointer
44 EGA/VGA 6845 data for intializing a video mode
45 ? ?
46 HDD As 41, but for HDD #2
47 ? ?
48 PCjr Keyboard translate table pointer
49 PCjr non keyboard translate table pointer!
4A AT-BIOS User alarm routine pointer
4B to
5F ? DesqView redirects IRQ0-7 to int 50-57
5C often used by networking software
60 to
67 User Free for user use - INT67 often software call for EMS drivers
68 to
6F ? ?
70 AT 8259 IRQ8 AT Real time Clock
71 AT 8259 IRQ9 AT LAN (often patched to IRQ2)
72 AT 8259 IRQA ?
73 AT 8259 IRQB ?
74 AT 8259 IRQC ?
75 AT 8259 IRQD AT 80287 Error (patched to IRQ2 for compatibility)
76 AT 8259 IRQE AT Hard disk (IDE types only)
77 AT 8259 IRQF ?
78 to
7F ? ?
80 to
F0 BASIC Used bu GWBASIC, BASICA, otherwise ?
F1 to
FF ? ?
As you can see, some interrupts are used as simple xxxx:xxxx address pointers,
some are for calling software routines, and some are generated by hardware and
call a user routine automaticly..
SO! What does all this mean? What it means is probably not a hell of a lot at
this stage... in the future, you will find this is a valuable referance of low
level tables when you come to nutting out a program that mysteriously performs
OUT's, direct memory reads etc...
For more in-depth instruction on the BIOS and dOS data areas, see norton's
programmer's guide to the IBM PC (first ed. pages 51-58 - good reading!!)
to round things off, I'll finish with another small demo ASM program that
shows off some more instructions...
Ever needed to move memory about FAST? how about fast reading from sequential
memory locations (or indeed writing..)??? There's a set of instructions
designed just for this. They are:
STOSB - write byte
STOSW - write word
LODSB - read byte
LODSW - read word
MOVSB - move byte
MOVSW - move word
*OUTSB - output byte to port
*OUTSW - output word to port
*INSB - input byte from port
*INSW - input word from port
* = only executeable on 286 or above!
All of these routines can be looped a given number of times - place the number
of repititions to be performed into the CX register and preface the
instruction with the letters REP - IE: REP MOVSB ...
The data comes from DS:SI (for LOD or OUT types) and goes to ES:DI (for STO or
OUT types). further, if you use OUT or IN instructions, they use the port in
DX for their reading/writing.
further note that the instructions alter their assosiated pointer register!! -
thus if you have SI=5312 and you do a LODS, atferwards SI will be one greater
or lower, depending on the setting of the Direction flag! - the direction flag
should always be set by you before using these instructions otherwise thids
could go the wrong way!! - for incrementing after read/writng, first execute
a CLD (Clear direction flag) instruction. For decrement after Read/Write,
first execute a STD (set direction flag) instruction. Note that a maximum of
64k can be moved in any one go, and that the segment registers are not altered
as a result of an instruction, only the offset pointers, so a 20 byte read
starting at 1000:FFFC will NOT read on into the next segment, but rather the
last 7 bytes will come starting from 1000:0000!!!!! this is a bad limitation
of the instructions, so don't get caught out!!!
THESE ARE VERY POWERFULL INSTRUCTIONS!!! ... let's say you wish to move a
chunk of memory from 3C00:2745 to 3212:5678 (assume a length of 2c0 bytes)
this does it:
CLD
MOV CX,02C0
MOV DS,3C00
MOV SI,2745
MOV ES,3212
MOV DI,5678
REP MOVSB
Dead simple, eh? If one divides CX by two and uses REP MOVSW then one gets a
2x speed transfer on 16 bit machines!!
This is te method used to scroll display memory in my second VGA Demo - it's
too slow to do smooth scrolling animation, but quite quick enough for simple
memory moves.
The actual speed can be calculated thus:
Instructions are measured in clock ticks... a clock tick is 1 divided by the
CPU clock frequency... On a 20MHz machine, each clock tick is 1/20million -
about 0.05 of a microsecond!!!
Let's take a MOVSW instruction - this takes 1 tick to read the instruction, 1
tick to process it, 2 ticks to read the word in, 1 tick to process, 2 ticks to
write it out, along with 2 RAM refresh ticks in the middle.. a total of 9
tics - so each MOVSB takes 9 x 0.05 uS = about 1/2 a microsecond....
A 64k move takes 65535x0.5uS = about 32.8 milliseconds!!!!
This translates into bieng able to move about 1.9MB in a second (At 20MHZ!!!!!)
The old 4.77MHz XT did about 1/4,770,000=21uS/tick - 0.18mS/MOVSW - 64k moved
in about eleven SECONDS!!! (That's indirectly why a 4.77MHz XT 640 RAM Test
[on bootup] takes about 3 minutes!)
The 386 and 486 are capable of running faster at the same clock speed because
they takes less ticks to execute the same instruction (They only do 1 RAM
refresh, and only take 1 tickto read or write a word) .. this is why a 286 and
a 386 (NOT 386 SX!!) don't run at the same speed even though they have th same
clock speed (all the instructions take less ticks on a 386 - not just the
MOVSW!)
If that isn't enough to keep your minds flowing, then I'll go he! It's
midnight, I'm going to bed! Until ASMVEG4, Cya's!!
.\\erlin